package com.test.es;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.elasticsearch.action.bulk.BulkRequestBuilder;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.MultiSearchResponse;
import org.elasticsearch.action.search.MultiSearchResponse.Item;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.DeleteByQueryRequest;
import org.elasticsearch.index.reindex.DeleteByQueryRequestBuilder;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.Before;
import org.junit.Test;

import com.alibaba.fastjson.JSONObject;

public class ESTest3 {

	private TransportClient client;

	public String createJson1(){
		String json = "{" +
		        "\"user\":\"kimchy\"," +
		        "\"postDate\":\"2013-01-30\"," +
		        "\"message\":\"trying out Elasticsearch\"" +
		    "}";
		return json;
	}
	
	public Map<String,Object> createJson2(){
		Map<String, Object> json = new HashMap<String, Object>();
		json.put("user","kimchy");
		json.put("postDate",new Date());
		json.put("message","trying out Elasticsearch");
		return json;
	}
	
	public JSONObject createJson3(){
		JSONObject json = new JSONObject();
		json.put("user", "zhangsan");
		json.put("postDate", new Date());
		json.put("message", "hello elasticsearch");
		return json;
	}
	
	public XContentBuilder createJson4() throws IOException{
		XContentBuilder builder = XContentFactory.jsonBuilder()
				.startObject()
				.field("user", "zhangfei").field("postDate", new Date()).field("message", "hello word").endObject();
		System.out.println(builder.string());
		return builder;
	}
		
	@Before
	public void testBefore() throws Exception {
		Settings settings = Settings.builder().put("cluster.name", "my-5i5j").build();
		client = new PreBuiltTransportClient(settings).addTransportAddress(new InetSocketTransportAddress(new InetSocketAddress("10.1.66.76", 9300)));
		//6.0.1 版本适用
		//client = new PreBuiltTransportClient(settings).addTransportAddress(new TransportAddress(new InetSocketAddress("10.1.66.76", 9300)));
	}

	/**
	 * 索引文档
	 * @throws Exception
	 */
	@Test
	public void testIndex()throws Exception{
		IndexResponse response = client.prepareIndex("twitter", "tweet", "1").setSource(createJson4()).execute().actionGet();
		// Index name
		String _index = response.getIndex();
		// Type name
		String _type = response.getType();
		// Document ID (generated or not)
		String _id = response.getId();
		// Version (if it's the first time you index this document, you will get: 1)
		long _version = response.getVersion();
		System.out.println("index = " + _index + ", type = " + _type + ", id = " + _id + ", version = " + _version);
	}
	
	/**
	 * 获取API
	 * @throws Exception
	 */
	@Test
	public void testGet()throws Exception{
		//GetResponse response = client.prepareGet("twitter", "tweet", "1").execute().actionGet();
		 GetResponse response = client.prepareGet("twitter", "tweet", "1")
				.setOperationThreaded(false)
				.execute().actionGet();
		 System.out.println(response.getSourceAsString());
	}
	
	/**
	 * 删除API
	 * @throws Exception
	 */
	@Test
	public void testDelete() throws Exception{
		DeleteResponse response = client.prepareDelete("twitter", "tweet", "1").execute().actionGet();
		//DeleteResponse response = client.prepareDelete("twitter", "tweet", "1").get();
		System.out.println(response.status().getStatus());
	}
	
	/**
	 * 更新API
	 * @throws Exception
	 */
	@Test
	public void testUpdate1()throws Exception{
		UpdateRequest request = new UpdateRequest("twitter", "tweet", "1").doc(XContentFactory.jsonBuilder()
				.startObject().field("gender", "male").field("message", "hello update").endObject());
		client.update(request).get();
	}
	
	@Test
	public void testUpdate2()throws Exception{
		UpdateResponse response = client.prepareUpdate("twitter", "tweet", "1")
				.setScript(new Script("ctx._source.gender = \"male\"")).get();
	}
	
	@Test
	public void testUpdate3()throws Exception{
		UpdateResponse response = client.prepareUpdate("twitter", "tweet", "1").setDoc(XContentFactory.jsonBuilder()
				.startObject()
				.field("happy", "basketball")
				.field("gender", "man")
				.endObject()).get();
		System.out.println(response.status().getStatus());
	}
	
	/**
	 * 先查询如果查询不到则信息
	 * 如果查询到 将 gender修改为 male，如果查询不到则新增
	 * user：关羽，gender：先生
	 * @throws Exception
	 */
	@Test
	public void testUpdate4()throws Exception{
		IndexRequest indexRequest = new IndexRequest("twitter", "tweet", "2").source(XContentFactory.jsonBuilder()
				.startObject()
				.field("user", "关羽")
				.field("gender", "先生")
				.endObject());
		UpdateRequest updateRequest = new UpdateRequest("twitter", "tweet", "2").doc(XContentFactory.jsonBuilder()
				.startObject()
				.field("user", "guanyu")
				.field("gender", "male")
				.endObject()).upsert(indexRequest);
		client.update(updateRequest).get();
	}
	
	/**
	 * 批处理（bulk ）
	 * 批量删除
	 * @throws Exception
	 */
	@Test
	public void testBulk1()throws Exception{
		BulkRequestBuilder bulkRequestBuilder = client.prepareBulk();
		bulkRequestBuilder.add(client.prepareDelete("twitter", "tweet", "1"));
		bulkRequestBuilder.add(new DeleteRequest("twitter", "tweet", "2"));
		bulkRequestBuilder.get();
	}
	
	/**
	 * 批量创建
	 * @throws Exception
	 */
	@Test
	public void testBulk2()throws Exception{
		BulkRequestBuilder bulkRequestBuilder = client.prepareBulk();
		bulkRequestBuilder.add(client.prepareIndex("twitter", "tweet", "1").setSource(XContentFactory.jsonBuilder()
				.startObject()
				.field("user", "关羽")
				.field("postDate", new Date())
				.field("message", "my name is guanyu")
				.endObject()));
		
		bulkRequestBuilder.add(client.prepareIndex("twitter", "tweet", "2").setSource(XContentFactory.jsonBuilder()
				.startObject()
				.field("user", "张飞")
				.field("postDate", new Date())
				.field("message", "my name is zhangfei")
				.endObject()));
		BulkResponse response = bulkRequestBuilder.get();
		if(response.hasFailures()){
			System.out.println(response.buildFailureMessage());
		}
	}
	
	/**
	 * 搜索API
	 * @throws Exception
	 */
	@Test
	public void testSearch1()throws Exception{
		/*
		SearchResponse response = client.prepareSearch("bank")
				.setTypes("account")
				.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
				.setQuery(QueryBuilders.termQuery("firstname", "lle"))
				.setPostFilter(QueryBuilders.rangeQuery("balance").from("10000").to("50000"))
				.setFrom(0).setSize(60).setExplain(true).get();
		SearchHits hits = response.getHits();
		for(SearchHit hit : hits){
			System.out.println(hit.getSourceAsString());
		}
		*/
		SearchResponse response = client.prepareSearch("bank").setTypes("account")
				.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
				//.setQuery(QueryBuilders.termQuery("age", 30))
				//.setQuery(QueryBuilders.rangeQuery("age").gt(30))
				.setQuery(QueryBuilders.rangeQuery("age").gte(30))
				.setPostFilter(QueryBuilders.rangeQuery("balance").from(10000).to(20000))
				.setFrom(0).setSize(10).get();
		SearchHits hits = response.getHits();
		for(SearchHit hit : hits){
			System.out.println(hit.getSourceAsString());
		}
		System.out.println("记录数：" + hits.getTotalHits());
	}
	
	/**
	 * 搜索
	 * 在java中使用scrolls
	 * @throws Exception
	 */
	@Test
	public void testScrolls()throws Exception{
		QueryBuilder queryBuilder = QueryBuilders.termQuery("age", 30);
		SearchResponse response = client.prepareSearch("bank")
				.setTypes("account")
				.setSearchType(SearchType.DEFAULT)
				.setScroll(new TimeValue(60000))
				.setQuery(queryBuilder)
				.setSize(100).get();
		while(true){
			SearchHits hits = response.getHits();
			for(SearchHit hit : hits){
				System.out.println(hit.getSourceAsString());
			}
		}
	}
	
	/**
	 * 多搜索API
	 * @throws Exception
	 */
	@Test
	public void testSearch2()throws Exception{
		SearchRequestBuilder search1 = client.prepareSearch("bank")
				.setTypes("account")
				.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
				.setQuery(QueryBuilders.queryStringQuery("Rice"))
				.setSize(10);
		
		SearchRequestBuilder search2 = client.prepareSearch("bank")
				.setTypes("account")
				.setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
				.setQuery(QueryBuilders.matchQuery("address", "Avenue"))
				.setSize(10);
		
		MultiSearchResponse response = client.prepareMultiSearch().add(search1).add(search2).get();
		Iterator<Item> iterators =  response.iterator();
		while(iterators.hasNext()){
			Item item = iterators.next();
			System.out.println(item.getResponse().toString());
		}
	}
	
	
	public static void main(String[] args) throws IOException {
		ESTest3 test3 = new ESTest3();
		test3.createJson4();
	}
}
